﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Contract.Business.Process;
using Contract.Business.Entity;
using Contract.Business.Filter;

namespace FastPizza.Testing
{
    [TestClass]
    public class UTVenda
    {
        #region Singleton
        private BEConfiguracao beConfiguracao;
        public BEConfiguracao config
        {
            get
            {
                if (beConfiguracao == null)
                    beConfiguracao = new BPConfiguracao().ObterTodos(new FEConfiguracao()).First();

                return beConfiguracao;
            }
        }

        private BPSubGrupoTamanho bpSubGrupoTamanho;
        public BPSubGrupoTamanho processSubGrupoTamanho
        {
            get
            {
                if (bpSubGrupoTamanho == null)
                    bpSubGrupoTamanho = new BPSubGrupoTamanho();

                return bpSubGrupoTamanho;
            }
        }

        private BPVenda bpVenda;
        public BPVenda processVenda
        {
            get
            {
                if (bpVenda == null)
                    bpVenda = new BPVenda();

                return bpVenda;
            }
        } 
        #endregion

        [TestMethod]
        public void TestePromocaoRefrigerante()
        {
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Bebidas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Refrigerante, (int)Tamanho.Litro15).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    CodigoSubGrupo = (int)SubGrupo.Refrigerante,
                    CodigoTamanho = (int)Tamanho.Litro15,
                    Preco = valorSubGrupoTamanhoOriginal
                }; 
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal;
                decimal valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;

                //Teste comprando um refrigerante
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Sunday, false, config);
                Assert.AreEqual<decimal>(0, valorTotal);

                //Teste comprando dois refrigerantes
                valor = valorOriginal;
                processVenda.aplicarPromocoes(produto, 2, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Sunday, false, config);
                Assert.AreEqual<decimal>(valorOriginal, valorTotal); 
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoSegundaFeira()
        {
            //Segunda - Na compra de uma pizza grande mais R$ 6,00 ganhe uma pizza pequena Classic ou mais R$ 8,00 ganhe uma pizza pequena Prime
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Pequeno,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal;
                valor = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Monday, false, config);
                Assert.AreEqual<decimal>(6, valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Monday, false, config);
                Assert.AreEqual<decimal>(8, valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoTercaFeira()
        {
            //Terça - Na compra de uma pizza grande a segunda pizza grande sai pela metade do preço!
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo(){ CodigoGrupo = (int)Grupo.Pizzas},
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Grande,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal, valorOriginal;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Tuesday, false, config);
                Assert.AreEqual<decimal>((valorOriginal / 2), valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Tuesday, false, config);
                Assert.AreEqual<decimal>((valorOriginal / 2), valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoQuartaFeira()
        {
            //Quarta - Na compra de uma pizza grande a segunda pizza grande sai pela metade do preço!
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas },
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Grande,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal, valorOriginal;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Wednesday, false, config);
                Assert.AreEqual<decimal>((valorOriginal / 2), valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Wednesday, false, config);
                Assert.AreEqual<decimal>((valorOriginal / 2), valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoQuintaFeira()
        {
            //Quinta - Na compra de qualquer pizza, a borda recheada é por nossa conta
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas },
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Grande,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal, valorOriginal;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Thursday, true, config);
                Assert.AreEqual<decimal>(valorOriginal, valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Thursday, true, config);
                Assert.AreEqual<decimal>(valorOriginal, valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoSextaFeira()
        {
            //Sexta - Na compra de uma pizza grande a segunda pizza grande sai pelo preço da pizza média!
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 1;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas },
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Grande,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal, valorOriginal;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;
                //Busca valor da pizza média
                decimal valorOriginalMedia = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, (int)Tamanho.Medio).Preco;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Friday, false, config);
                Assert.AreEqual<decimal>(valorOriginalMedia, valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                //Busca valor da pizza média
                valorOriginalMedia = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, (int)Tamanho.Medio).Preco;
                valorOriginal = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                valor = valorOriginal;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Friday, false, config);
                Assert.AreEqual<decimal>(valorOriginalMedia, valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoSabado()
        {
            //Sábado - Na compra de duas pizzas grandes, mais R$ 5,00 ganhe uma pizza pequena classic, ou mais R$ 7,00 ganhe uma pizza pequena prime
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 2;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas },
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Pequeno,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal;
                valor = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Saturday, false, config);
                Assert.AreEqual<decimal>(5, valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                valor = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Saturday, false, config);
                Assert.AreEqual<decimal>(7, valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }

        [TestMethod]
        public void TestePromocaoDomingo()
        {
            //Domingo - Na compra de duas pizzas grandes, mais R$ 5,00 ganhe uma pizza pequena classic, ou mais R$ 7,00 ganhe uma pizza pequena prime
            try
            {
                List<BEVendaItem> itens = new List<BEVendaItem>();

                //Criando lista de itens
                #region Adicionando itens à venda
                BEVendaItem item = new BEVendaItem();
                item.CodigoTamanho = (int)Tamanho.Grande;
                item.Produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                item.Quantidade = 2;
                itens.Add(item);
                #endregion

                //Criando produto
                #region Criando o Produto
                BEProduto produto = new BEProduto()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas }
                };
                #endregion

                //Criando o subgrupotamanho
                #region Criando o subgrupotamanho
                decimal valorSubGrupoTamanhoOriginal = processSubGrupoTamanho.ObterEntidade((int)SubGrupo.Classic, (int)Tamanho.Pequeno).Preco;
                BESubGrupoTamanho subGrupoTamanho = new BESubGrupoTamanho()
                {
                    SubGrupo = new BESubGrupo() { CodigoGrupo = (int)Grupo.Pizzas },
                    CodigoSubGrupo = (int)SubGrupo.Classic,
                    CodigoTamanho = (int)Tamanho.Pequeno,
                    Preco = valorSubGrupoTamanhoOriginal
                };
                #endregion

                #region Realizando o teste
                decimal valor, valorTotal;
                valor = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;

                //Teste comprando uma pizza classic
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Saturday, false, config);
                Assert.AreEqual<decimal>(5, valorTotal);

                //Teste comprando uma pizza prime
                subGrupoTamanho.CodigoSubGrupo = (int)SubGrupo.Prime;
                valor = processSubGrupoTamanho.ObterEntidade(subGrupoTamanho.CodigoSubGrupo, subGrupoTamanho.CodigoTamanho).Preco;
                processVenda.aplicarPromocoes(produto, 1, ref valor, out valorTotal, subGrupoTamanho, itens, DayOfWeek.Saturday, false, config);
                Assert.AreEqual<decimal>(7, valorTotal);
                #endregion
            }
            catch (Exception)
            {
                Assert.IsTrue(false);
            }
        }
    }

    #region Enumeraveis

    public enum Grupo
    {
        Pizzas = 1,
        Bebidas = 2,
        Massas = 3
    }

    public enum Tamanho
    {
        Pequeno = 1,
        Medio = 2,
        Grande = 3,
        Litro15 = 4,
        LongNeck = 5,
        Litro1 = 6
    }

    public enum SubGrupo
    {
        Classic = 1,
        Prime = 2,
        Refrigerante = 3,
        Suco = 4,
        Cerveja = 5
    }

    #endregion
}
